#include <conf.h>
#include <kernel.h>
#include <proc.h>
#include <q.h>

unsigned long currSP;   /* REAL sp of current process */
extern int ctxsw(int, int, int, int);
/*-----------------------------------------------------------------------
 * resched  --  reschedule processor to highest priority ready process
 *
 * Notes:       Upon entry, currpid gives current process id.
 *              Proctab[currpid].pstate gives correct NEXT state for
 *                      current process if other than PRREADY.
 *------------------------------------------------------------------------
 */
int resched()
{
int prev,next;
if(getschedclass() == 1)
{
        int i;
	q[currpid].qkey=proctab[currpid].pprio;

	for(i=0;i<50;i++)
	{
		if(proctab[i].pstate==PRREADY)
         	  q[i].qkey++;
	} 

/*
q[currpid].qkey=proctab[currpid].pprio;

     //   prev =q[rdytail].qprev;
	prev = getlast(rdytail);
           while(prev!=0 )
            {
                 q[prev].qkey++;
                 prev=q[prev].qprev;
            }
*/
	register struct pentry  *optr;  /* pointer to old process entry */
        register struct pentry  *nptr;  /* pointer to new process entry */

        /* no switch needed if current process priority higher than next*/

        if ( ( (optr= &proctab[currpid])->pstate == PRCURR) &&
           (lastkey(rdytail)<optr->pprio)) {
                return(OK);
        }

        /* force context switch */

        if (optr->pstate == PRCURR) {
                optr->pstate = PRREADY;
                insert(currpid,rdyhead,optr->pprio);
        }

        /* remove highest priority process at end of ready list */

        nptr = &proctab[ (currpid = getlast(rdytail)) ];
        nptr->pstate = PRCURR;          /* mark it currently running    */
#ifdef  RTCLOCK
        preempt = QUANTUM;              /* reset preemption counter     */
#endif

        ctxsw((int)&optr->pesp, (int)optr->pirmask, (int)&nptr->pesp, (int)nptr->pirmask);

        /* The OLD process returns here when resumed. */
        return OK;

}
if (getschedclass() == 2)
        {
        STATWORD ps;
        disable(ps);

        register struct pentry  *optr;  /* pointer to old process entry */
        register struct pentry  *nptr;  /* pointer to new process entry */


        optr= &proctab[currpid];
        if(currpid!=0)                  /* Check if null process was the current process*/
        {optr->quantum=preempt;}       /* Store preempt value in the current process's quantum*/
        else
        {optr->quantum=0;}             /* Set quantum = 0 for null process since null always has the lowest priority*/


        int i,j,k,count=0,qcount=0;
        for(j=0;j<NPROC;j++)
        {
                if((proctab[j].pstate==PRREADY)&&(proctab[j].quantum==0))      /*count number of ready processes with quantum =0*/
                        {
                         qcount++;
                         }
        }
        if(qcount==0)               /*if all ready processes have quantum = 0,then current epoch has ended*/
        {
                for(k=0;k<NPROC;k++)
                        {
                                if(proctab[k].pstate!=PRFREE)
                                {
                                        if(proctab[k].quantum==0)
                                        {
                                        proctab[k].goodness=proctab[k].quantum+proctab[k].pprio;
                                        proctab[k].quantum=proctab[k].pprio;
                                        if(proctab[k].pstate==PRREADY)
                                        {
                                        dequeue(k);
                                        insert(k,rdyhead,proctab[k].goodness);
                                        }
                                        }
                                        else
                                        {
                                        proctab[k].goodness=proctab[k].quantum+proctab[k].pprio;
                                        proctab[k].quantum=proctab[k].pprio+(proctab[k].quantum/2);
                                        if(proctab[k].pstate==PRREADY)
                                        {dequeue(k);
                                        insert(k,rdyhead,proctab[k].goodness);
                                        }
                                        }
                                }

                        }

                }




        /* force context switch */



        if((optr->quantum==0))          /*If epoch is not over and process has used up its quantum*/
        {       optr->goodness=0;
        }

        if (optr->pstate == PRCURR) {
                optr->pstate = PRREADY;
                insert(currpid,rdyhead,optr->goodness);
        }

        /* remove highest priority process at end of ready list */

        nptr = &proctab[ (currpid = getlast(rdytail)) ];
        nptr->pstate = PRCURR;          /* mark it currently running    */
#ifdef  RTCLOCK
        preempt = nptr->quantum;               /* reset preemption quantum     */
#endif
        restore(ps);

        ctxsw((int)&optr->pesp, (int)optr->pirmask, (int)&nptr->pesp, (int)nptr->pirmask);

        /* The OLD process returns here when resumed. */
        return OK;
}

}
